home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
pctj0187.arc
/
EGAFONT.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-01-28
|
10KB
|
377 lines
page 80,132
title egafont -- ega font routines for Turbo Pascal
;
; 2 entry points
; [0] 1. EGAstring(s : string; x, y, color, direction:
; integer; VAR f: fontrecord);
; [3] 2. EGAinitfont(f: fontarray);
;
; Because this runs under Turbo Pascal, no direct references
; are made to the code segment. However registers are set up to
; provide access to assembled tables when needed.
; John T. Cockerham, November 1986
; Font table layout
fontptr equ 0 ;pointer to the actual font
fonthit equ 4 ;height of characters
ftype equ 6 ;type of font; 0=fixed
fwidth equ 8 ;width of characters
FontTbSize equ 10
;
videoio equ 10H ;BIOS interrupt vector
FontInfo equ 1130H ;Font Information Request code
StdFont equ 0200H ;Standard Font Info Code
DblFont equ 0300H ;Double Dot Info Code
GDCSet equ 00H ;GDC set/reset register
GDCEnab equ 01H ;GDC enable set/reset
GDCAlu equ 03H ;GDC Alu operation and shift
GDCMask equ 08H ;GDC bit mask
GDC equ 03CEH ;The GDC data register pair
;
FontWidth equ 8 ;The width of all fonts is 8
Horiz equ 0 ;Horizontal directions constant
Vert_Up equ 1 ;Vertical up going direction
ScreenWidth equ 80 ;Screen is 80 columns wide
;
; stack layout for string and character calls
;
stx equ [bp+20]
x0 equ word ptr [bp+18]
y0 equ word ptr [bp+16]
color equ word ptr [bp+14]
direct equ word ptr [bp+12]
op equ word ptr [bp+10]
font equ dword ptr [bp+6]
retx equ word ptr [bp+4]
oldds equ word ptr [bp+2]
oldbp equ word ptr [bp]
x1 equ word ptr [bp-2]
y1 equ word ptr [bp-4]
x2 equ word ptr [bp-6]
y2 equ word ptr [bp-8]
csx equ word ptr [bp-10]
pts equ word ptr [bp-12]
fp equ [bp-16] ;address pointer dd here
j equ word ptr [bp-18]
b1 equ word ptr [bp-20]
b2 equ word ptr [bp-22]
stpt equ word ptr [bp-24]
c1 equ word ptr [bp-26]
;
; entry points
;
egafont segment 'code'
assume cs:egafont,es:nothing,ds:nothing
jmp dostr1
jmp initf1
db 'EGAFONT' ;So it can be found
;
;mask1 is the masks for the left byte
;bittab is the bit table for setting dots
;
mask1 db 0ffh, 07fh, 03fh, 01fh, 00fh, 007h, 003h, 001h
bittab db 080h, 040h, 020h, 010h, 008h, 004h, 002h, 001h
;
; Do string
;
dostr proc near
dostr1: push ds
push bp ;set up the stack
mov bp,sp ;new stack pointer
sub sp,30 ;carve out space on the stack
call dost2 ;get offset into code segment
dost2 proc near
dost2 endp ;dummy procedure segment
dost3: pop ax ;this is our return address
sub ax,offset dost3 ;now we have start of the segment
mov csx,ax ;in case we need it
mov stpt,0 ;this is our string pointer
str1:
inc stpt ;top of character loop
les bx,stx ;get the string address
mov al,es:[bx] ;this is the length of the string
xor ah,ah ;zap the high byte
cmp stpt,ax ;look at where we are in the string
jbe strx1 ;all done?
jmp strxt
strx1: add bx,stpt ;this is the character
mov al,es:[bx] ;
xor ah,ah ;zot the byte
mov c1,ax ;the character is in hand
les bx,font ;get the font pointer
mov ax,es:fonthit[bx]
mov pts,ax ;height of characters
;
; here calculate the font pointer
;
mul c1 ;this makes the offset
lds si,es:fontptr[bx]; this is the start of the font
add si,ax ;this is the start of the character
mov fp,si
mov fp[2],ds ;save the point for a moment
;
; this is the main painting loop
;
mov j,1 ;start on the 1 line of the font
dost6: mov ax,x0
mov x1,ax ;p1 := p0
mov ax,y0
mov y1,ax
dost7: lds si,dword ptr fp ;get the font point
inc word ptr fp ;move the font point
mov dl,[si] ;this is the actual font byte
xor dh,dh ;clean up the high byte
;
mov ax,direct ;branch on direction
cmp ax,Horiz ;handle the regular case
jne dostup
call fbhor ;horizontal painting
inc y0 ;bump for the next "line"
jmp short dostlnx
dostup: call fbvert
mov ax,direct ;update the point the next font line
cmp ax,Vert_Up ;this is the up direction
jne dost11
inc x0
jmp short dostlnx
dost11: dec x0
dostlnx:
inc word ptr j ;j is the font pointer
mov ax,j ;get the pointer for comparison
cmp ax,pts ;another point?
ja dostx ;yes again
jmp dost6
;
; move the pointer to the next position in the string
;
dostx: mov ax,direct
mov bx,FontWidth
mov cx,pts
cmp ax,Horiz ;check the direction move accordingly
jne dost13
add x0,bx ;move across the screen
sub y0,cx ;and to the top of the character box
jmp str1
dost13: cmp ax,Vert_Up ;this is the up direction
jne dost14
sub y0,bx ;move up the screen
sub x0,cx ;and to the top of the char box
jmp str1 ;another character
dost14: add y0,bx ;Vertical Down default
add x0,cx ;the next box is down the screen
jmp str1 ;get the next character
;
; clean up and exit
;
strxt: mov sp,bp ;dissolve the stack
pop bp
pop ds
ret 18 ;drop 18 bytes off the stack
dostr endp
;
; passed one pointer to the font information array
;
farray equ dword ptr [bp+4]
initf proc near
initf1:
push bp
mov bp,sp ;stack preamble
; get the first font information
push bp ;Bios will clobber our bp
mov ax,FontInfo ;information request
mov bx,StdFont ;on the 8 by 14 font
int videoio ;
mov ax,bp ;get the returned bp pointer
pop bp ;es:ax now has the font address
lds di,farray ;ds:di points to start of the array
mov fontptr[di],ax ;the offset
mov fontptr[di+2],es ;and the segment
mov word ptr fonthit[di],14 ;this is the size in points
mov word ptr ftype[di],0 ;this is a fixed font
mov word ptr fwidth[di],8 ;and it is 8 pixels wide
; get the double dot font
push bp ;save the bp
mov ax,FontInfo ;request information
mov bx,DblFont ;on the double dot font
int videoio ;ask for it from the bios
mov ax,bp ;get the pointers
pop bp ;and recover bp
lds di,farray ;get the array pointer
add di,FontTbSize ;move to the next entry in the array
mov fontptr[di],ax ;the offset
mov fontptr[di+2],es;and the segment
mov word ptr fonthit[di],8 ;this is the size in points
mov word ptr ftype[di],0 ;this is a fixed font
mov word ptr fwidth[di],8 ;and it is 8 pixels wide
pop bp
ret 4 ;drop 4 bytes off of the stack
initf endp
;
; paint a horizontal byte
; dx = font byte
fbhor proc near
mov ax,x1 ;calculate the various offsets
and ax,07h ;the offset into the bitstring
mov si,ax ;and get set to index
mov cx,ax
ror dl,cl ;this rotates it
xor dh,dh ;for security
;
add si,csx ;this is the cseg offset
mov al,cs:Mask1[si] ;get the particular mask byte
mov cx,ax
and cx,dx ;this is one form of the character
mov b1,cx ;the left portion
not ax
and ax,dx ;this is the right portion
mov b2,ax
;
mov ax,x1 ;get set to calculate the EGA address
mov x2,ax ;from points x2 and y2
mov ax,y1 ;in the stack
mov y2,ax
call egacalc ;get es:di set to the EGA buffer
mov ax,color ;fix the set/reset mechanism
mov bx,0fh ;in all planes to the color
call setreset ;
mov ax,op ;now get the ALU all set up
call egaalu ;done
;
; pixel string straddles two bytes
;
mov ax,b1 ;first mask
call egamask
mov al,es:[di] ;get the byte latched in
mov es:[di],al ;latches and set reset do all
inc di ;move to the next byte
mov ax,b2
call egamask ;this is the next byte
mov al,es:[di]
mov es:[di],al ;all done with both bytes
;
; all done clean up
;
mov ax,0ffH ;reset the mask
call egamask
xor ax,ax
xor bx,bx
call setreset
xor ax,ax
call egaalu ;reset the hardware
ret
fbhor endp
;
; Paint Vertical Byte depends on point access routines
; paint the byte at point p1
;
fbvert proc near
mov ax,x1 ;make copy of the point
mov x2,ax
mov ax,y1
add ax,FontWidth ;start off
mov y2,ax ;from the character
mov cx,FontWidth ;get set to loop
mov bx,080H ;start from the left edge of the byte
fbv1: mov ax,dx ;get the font byte
and ax,bx ;is the bit set
jz fbv2 ;no then skip this drawing
push dx
push bx
push cx
call dot ;draw the dot at point #2
pop cx
pop bx ;the dot is drawn
pop dx
fbv2:
shr bx,1 ;look at the next bit
cmp direct,Vert_Up ;do we bump or drop to the next point
jnz fbv3
dec y2 ;this is painting up
jmp short fbv4
fbv3: inc y2
fbv4: loop fbv1
ret
fbvert endp
;
; Set EGA GDC Bitmask
; ax = mask value
egamask proc near
mov ah,al ;get value in high byte
mov al,GDCMask ;set up the IO instruction
mov dx,GDC
out dx,ax ;put it out
ret
egamask endp
;
; Set EGA set reset registers
; ax = value to fill; bx = planes
setreset proc near
mov ah,al ;get the value in the right place
mov al,GDCSet ;point to the GDC set register
mov dx,GDC ;set up IO instruction
out dx,ax ;first half of instruction
mov ah,bl ;these are the enable bits
mov al,GDCEnab ;this in the enable register
out dx,ax ;talk to the device
ret
setreset endp
;
; Set EGA GDC Alu operation and shift
;
egaalu proc near
mov ah,al ;get value in high byte
mov al,GDCAlu ;set up the IO instruction
mov dx,GDC
out dx,ax ;put it out
ret
egaalu endp
;
; calculate EGA address
; x2, y2 in the stack
egacalc proc near
mov ax,y2
mov cx,ScreenWidth
mul cx ;get the offset
mov bx,x2 ;now figure offset within the row
mov cx,3
shr bx,cl ;strip down to a byte address
add ax,bx
mov di,ax ;di is now set
mov ax,0a000H ;this is the screen segment
mov es,ax
nop
ret
egacalc endp
;
; dot -- draw a dot
;
dot proc near
call egacalc ;get es:di to point to the byte
mov ax,x2 ;figure out the bit offset
and ax,07H ;this is the offset in the byte
mov bx,csx ;get set to address ourselves
add bx,ax ;now point within the bittab table
mov ah,cs:bittab[bx];get the mask value in ax
mov al,GDCMask ;isolate to the bit in question
mov dx,GDC ;talk to the GDC
out dx,ax ;the mask is set
mov ax,op ;set up the operation
mov ah,al ;get to the upper byte
mov al,GDCAlu ;this is the ALU
out dx,ax ;done setting operation
mov ax,color ;this is the color
mov bx,0FH ;into set/reset
call setreset
mov ch,es:[di] ;get the ram byte latched in
mov byte ptr es:[di],0FFH;set reset fills in the color
xor ax,ax ;turn off the ALU
call egaalu
xor ax,ax ;and set reset
xor bx,bx
call setreset
mov ax,0ffh ;now turn on the bitmap
call egamask
ret ;all done
dot endp
egafont ends
end